﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace STSdb.MTL
{
    /// <summary>
    /// Intended to store all STSdbMTLEngine(s) for your application in a static class.
    /// <para>Gives ability to access all engines by name.</para>
    /// </summary>
    public static class Engines
    {
        static ReaderWriterLockSlim _sync_engines = new ReaderWriterLockSlim();
        static Dictionary<string, STSdbMTLengine> _engines = new Dictionary<string, STSdbMTLengine>();

        /// <summary>
        /// Remote Commands Coordinator. Gives ability to make queries on different named engines and send answer as strings back.
        /// </summary>
        public static RemoteCommandsCoordinator _RMQC = new RemoteCommandsCoordinator();

        /// <summary>
        /// Adds named engine, if engine name is found then engine instance will be changed on the new one
        /// </summary>
        /// <param name="engineName"></param>
        /// <param name="engine"></param>
        public static void AddEngine(string engineName,STSdbMTLengine engine)
        {
            _sync_engines.EnterWriteLock();
            try
            {
                STSdbMTLengine e = null;                

                if (_engines.TryGetValue(engineName, out e))
                {
                    //trying to dispose the previous value
                    e.Dispose();

                    //settign new engine
                    _engines[engineName] = engine;

                    return;
                }

                _engines.Add(engineName, engine);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                _sync_engines.ExitWriteLock();
            }
        }

        /// <summary>
        /// Removes engine
        /// </summary>
        /// <param name="engineName"></param>
        public static void RemoveEngine(string engineName)
        {
            _sync_engines.EnterWriteLock();
            try
            {
                STSdbMTLengine e = null;
                if (_engines.TryGetValue(engineName, out e))
                {
                    //trying to dispose the previous value
                    e.Dispose();
                    //removes engine from the staorage
                    _engines.Remove(engineName);
                }

            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                _sync_engines.ExitWriteLock();
            }
        }


        /// <summary>
        /// Returns engine by name.
        /// <para>Can return NULL if the engine is not found</para>
        /// </summary>
        /// <param name="engineName"></param>
        /// <returns></returns>
        public static STSdbMTLengine GetEngine(string engineName)
        {

            _sync_engines.EnterReadLock();
            try
            {
                STSdbMTLengine e = null;
                _engines.TryGetValue(engineName, out e);

                return e;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                _sync_engines.ExitReadLock();
            }

        }

        /// <summary>
        /// Disposes all engines and clears engines storage
        /// </summary>
        public static void Dispose()
        {
            _sync_engines.EnterWriteLock();
            try
            {
                foreach (var engine in _engines)
                {
                    engine.Value.Dispose();
                }

                _engines.Clear();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                _sync_engines.ExitWriteLock();
            }
        }



        


    }
}
